// Utility sketch to explore DS1307 and
// demonstrate SoftI2cMaster and TwiMaster
//
#include <avr/pgmspace.h>
#include <I2cMaster.h>

// Pins for DS1307 with hardware i2c
// connect SCL to Arduino 168/328 analog pin 5
// connect SDA to Arduino 168/328 analog pin 4

// Instance of class for hardware master with pullups enabled
TwiMaster rtc(true);

// i2c 8-bit address for DS1307. low bit is read/write
#define DS1307ADDR 0XD0


//------------------------------------------------------------------------------
/*
 * Read 'count' bytes from the DS1307 starting at 'address'
 */
uint8_t readDS1307(uint8_t address, uint8_t *buf, uint8_t count) {
  // issue a start condition, send device address and write direction bit
  if (!rtc.start(DS1307ADDR | I2C_WRITE)) return false;

  // send the DS1307 address
  if (!rtc.write(address)) return false;

  // issue a repeated start condition, send device address and read direction bit
  if (!rtc.restart(DS1307ADDR | I2C_READ))return false;

  // read data from the DS1307
  for (uint8_t i = 0; i < count; i++) {

    // send Ack until last byte then send Ack
    buf[i] = rtc.read(i == (count-1));
  }

  // issue a stop condition
  rtc.stop();
  return true;
}


void setup(void) {
  Serial.begin(9600);
}

//------------------------------------------------------------------------------
/** Store and print a string in flash memory.*/
#define PgmPrint(x) SerialPrint_P(PSTR(x))
/** Store and print a string in flash memory followed by a CR/LF.*/
#define PgmPrintln(x) SerialPrintln_P(PSTR(x))

//------------------------------------------------------------------------------
/*
 * Print a string in flash memory to the serial port.
 */
static void SerialPrint_P(PGM_P str) {
  for (uint8_t c; (c = pgm_read_byte(str)); str++) Serial.write(c);
}

//------------------------------------------------------------------------------
/*
 * Print a string in flash memory followed by a CR/LF.
 */

static  void SerialPrintln_P(PGM_P str) {
  SerialPrint_P(str);
  Serial.println();
}

//-------------------------------------------------------------------------------
// day of week U.S. convention
char *Ddd[] = {"Bad", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

//------------------------------------------------------------------------------
void hexPrint(uint8_t v) {
  Serial.print(v >> 4, HEX);
  Serial.print(v & 0XF, HEX);
}

void displayTime(void) {
  uint8_t r[8];
  if (!readDS1307(0, r, 8)) {
    PgmPrintln("Read Failed for display time");
    return;
  }
  
  for(int i=0;i<8;i++)
    Serial.print(r[i]);
    
  PgmPrint("The current time is ");
  // month
  hexPrint(r[5]);
  Serial.write('/');
  // day
  hexPrint(r[4]);
  PgmPrint("/20");
  // year
  hexPrint(r[6]);
  Serial.write(' ');
  Serial.print(Ddd[r[3] < 8 ? r[3] : 0]);
  Serial.write(' ');
  // hour
  hexPrint(r[2]);
  Serial.write(':');
  // minute
  hexPrint(r[1]);
  Serial.write(':');
  // second
  hexPrint(r[0]);
  Serial.println();
  PgmPrint("Control: ");
  hexPrint(r[7]);
  Serial.println();
}

void loop(void) {
  Serial.println();
  displayTime();
  delay(2000);
}
